package io.jpress.commons.oauth2.connector;

import com.alibaba.fastjson.JSONObject;
import io.jboot.core.http.JbootHttpKit;
import io.jboot.utils.StrUtils;
import io.jpress.commons.oauth2.OauthConnector;
import io.jpress.commons.oauth2.OauthUser;

import java.util.HashMap;
import java.util.Map;

public class DingdingConnector extends OauthConnector {
    public DingdingConnector(String name, String appkey, String appSecret) {
        super(name, appkey, appSecret);
    }

    @Override
    public String createAuthorizeUrl(String state) {
        //https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI
        StringBuilder sb = new StringBuilder("https://oapi.dingtalk.com/connect/qrconnect?");
        sb.append("appid=" + getClientId());
        sb.append("&response_type=code");
        sb.append("&scope=snsapi_login");
        sb.append("&state=" + state);
        sb.append("&redirect_uri=" + getRedirectUri());    //"http://b5ad905b.ngrok.io");http://127.0.0.1:8080/callback

        return sb.toString();
    }

    protected JSONObject getAccessToken() {

        //https://oapi.dingtalk.com/sns/gettoken?appid=APPID&appsecret=APPSECRET
        StringBuilder urlBuilder = new StringBuilder("https://oapi.dingtalk.com/sns/gettoken?");
        urlBuilder.append("appid=" + getClientId());
        urlBuilder.append("&appsecret=" + getClientSecret());

        String url = urlBuilder.toString();

        String httpString = httpGet(url);

        return JSONObject.parseObject(httpString);
    }

    protected JSONObject getPersistentCode(String code,String access_token) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type","application/json");

        StringBuilder paramsBuilder = new StringBuilder("{\"tmp_auth_code\":\""+code+"\"}");
        String postData = paramsBuilder.toString();
        //获取用户授权的持久授权码
        String url = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token=" + access_token;
        String httpString = httpPost(url, null, headers, postData);
        if (StrUtils.isBlank(httpString)) {
            return null;
        }
        return JSONObject.parseObject(httpString);
    }

    protected JSONObject getSnsToken(String accessToken,String persistentCode, String openId){
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type","application/json");

        StringBuilder paramsBuilder = new StringBuilder("{\"persistent_code\":\""+persistentCode+"\",\"openid\":\""+openId+"\"}");
        String postData = paramsBuilder.toString();

        String url = "https://oapi.dingtalk.com/sns/get_sns_token?access_token=" + accessToken;
        String httpString = httpPost(url, null, headers, postData);
        if (StrUtils.isBlank(httpString)) {
            return null;
        }
        return JSONObject.parseObject(httpString);
    }
    @Override
    protected OauthUser getOauthUser(String code) {
        JSONObject tokenJson = getAccessToken();
        String accessToken = tokenJson.getString("access_token");

        JSONObject persistentCodes = getPersistentCode(code,accessToken);
        String persistentCode = persistentCodes.getString("persistent_code");
        String openId = persistentCodes.getString("openid");

        JSONObject snsTokens = getSnsToken(accessToken,persistentCode,openId);
        String snsToken = snsTokens.getString("sns_token");

        String url = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token=" + snsToken ;
        String httpString = httpGet(url);

        if (StrUtils.isBlank(httpString)) {
            return null;
        }

        JSONObject json = JSONObject.parseObject(httpString);
        JSONObject userInfo = json.getJSONObject("user_info");

        OauthUser user = new OauthUser();
        //nick、unionid、dingId、openid
        user.setAvatar(userInfo.getString("unionid"));
        user.setNickname(userInfo.getString("nick"));
        user.setOpenId(userInfo.getString( "openid"));
        user.setSource(getName());

        return user;
    }
}

